# ******************************************************************************
#  Copyright (c) 2021-2022. Kneron Inc. All rights reserved.                   *
# ******************************************************************************

from ...KPBaseClass.StructureBase import BufferBase
from ...KPStructure import InfCropBoxBuffer, HwPreProcInfoBuffer
from ...KPEnum import *
from ...KPConstant import Const
from typing import List
import ctypes


class GenericRawImageHeaderBuffer(BufferBase):
    """GenericRawImageHeader structure"""
    _pack_ = 4
    _fields_ = [('_inference_number', ctypes.c_uint32),
                ('_model_id', ctypes.c_uint32),
                ('_width', ctypes.c_uint32),
                ('_height', ctypes.c_uint32),
                ('_resize_mode', ctypes.c_uint32),
                ('_padding_mode', ctypes.c_uint32),
                ('_image_format', ctypes.c_uint32),
                ('_normalize_mode', ctypes.c_uint32),
                ('_crop_count', ctypes.c_uint32),
                ('_inf_crop', InfCropBoxBuffer * Const.MAX_CROP_BOX.value)]

    def _init_buffer(self,
                     width: int = 0,
                     height: int = 0,
                     resize_mode: ResizeMode = ResizeMode.KP_RESIZE_ENABLE,
                     padding_mode: PaddingMode = PaddingMode.KP_PADDING_CORNER,
                     image_format: ImageFormat = ImageFormat.KP_IMAGE_FORMAT_RGB565,
                     normalize_mode: NormalizeMode = NormalizeMode.KP_NORMALIZE_KNERON,
                     inference_number: int = 0,
                     model_id: int = 0,
                     inference_crop_box_buffer_list: List[InfCropBoxBuffer] = []) -> None:
        assert 0 <= width
        assert 0 <= height
        assert 0 <= inference_number
        assert 0 <= model_id

        self._width = width
        self._height = height
        self._resize_mode = resize_mode.value
        self._padding_mode = padding_mode.value
        self._image_format = image_format.value
        self._normalize_mode = normalize_mode.value
        self._inference_number = inference_number
        self._model_id = model_id
        self._crop_count = len(inference_crop_box_buffer_list)
        self._inf_crop = (InfCropBoxBuffer * Const.MAX_CROP_BOX.value)(*inference_crop_box_buffer_list)


class GenericRawResultHeaderBuffer(BufferBase):
    """GenericRawResultHeader structure"""
    _pack_ = 4
    _fields_ = [('_inference_number', ctypes.c_uint32),
                ('_crop_number', ctypes.c_uint32),
                ('_num_output_node', ctypes.c_uint32),
                ('_product_id', ctypes.c_uint32),
                ('_hw_pre_proc_info', HwPreProcInfoBuffer)]

    def _init_buffer(self,
                     inference_number: int = 0,
                     crop_number: int = 0,
                     num_output_node: int = 0,
                     product_id: int = 0,
                     hw_pre_proc_info: HwPreProcInfoBuffer = HwPreProcInfoBuffer()) -> None:
        assert 0 <= inference_number
        assert 0 <= crop_number
        assert 0 <= num_output_node
        assert 0 <= product_id

        self._inference_number = inference_number
        self._crop_number = crop_number
        self._num_output_node = num_output_node
        self._product_id = product_id
        self._hw_pre_proc_info = hw_pre_proc_info


class GenericRawBypassPreProcImageHeaderBuffer(BufferBase):
    """GenericRawBypassPreProcImageHeader structure"""
    _pack_ = 4
    _fields_ = [('_inference_number', ctypes.c_uint32),
                ('_model_id', ctypes.c_uint32),
                ('_image_buffer_size', ctypes.c_uint32)]

    def _init_buffer(self,
                     inference_number: int = 0,
                     image_buffer_size: int = 0,
                     model_id: int = 0) -> None:
        assert 0 <= inference_number
        assert 0 <= image_buffer_size
        assert 0 <= model_id

        self._inference_number = inference_number
        self._image_buffer_size = image_buffer_size
        self._model_id = model_id


class GenericRawBypassPreProcResultHeaderBuffer(BufferBase):
    """GenericRawBypassPreProcResultHeader structure"""
    _pack_ = 4
    _fields_ = [('_inference_number', ctypes.c_uint32),
                ('_crop_number', ctypes.c_uint32),
                ('_num_output_node', ctypes.c_uint32),
                ('_product_id', ctypes.c_uint32)]

    def _init_buffer(self,
                     inference_number: int = 0,
                     crop_number: int = 0,
                     num_output_node: int = 0,
                     product_id: int = 0) -> None:
        assert 0 <= inference_number
        assert 0 <= crop_number
        assert 0 <= num_output_node
        assert 0 <= product_id

        self._inference_number = inference_number
        self._crop_number = crop_number
        self._num_output_node = num_output_node
        self._product_id = product_id
